#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "calc.h"

char inbuf[1024] = {0};
char *ic = inbuf;
TokenDesc gtoken = {
    .type = T_NONE,
    .tkbuf = {0}
};

TokenType get_token(Token td)
{
    int c, i = 0;
    char buf[MAXTOKEN] = {0};

#define CONDJMP() do {\
    if (td->type == T_NUM)\
        goto finishnum;\
    } while (0)

    td->type = T_NONE;
    memset(td->tkbuf, 0, sizeof(td->tkbuf));

    while ((c = *ic) != '\0') {
        if (i >= MAXTOKEN) {
            fprintf(stderr, "Token too long...\n");
            exit(1);
        }

        if (isdigit(c) || c == '.') {
            buf[i++] = *ic++;
            td->type = T_NUM;
            continue;
        } else if (isspace(c) && c != '\n') {
            CONDJMP();
            ++ic;
            continue;
        } else {
            switch (c) {
                case '+':
                    CONDJMP();
                    td->type = T_ADD;
                    break;
                case '-':
                    CONDJMP();
                    td->type = T_SUB;
                    break;
                case '*':
                    CONDJMP();
                    td->type = T_MULTI;
                    break;
                case '/':
                    CONDJMP();
                    td->type = T_DIV;
                    break;
                case '(':
                    CONDJMP();
                    td->type = T_LP;
                    break;
                case ')':
                    CONDJMP();
                    td->type = T_RP;
                    break;
                case '\n':
                    CONDJMP();
                    td->type = T_EOF;
                    break;
                default:
                    fprintf(stderr, "invalid character: %c\n", c);
                    exit(1);
            }
            ++ic;
            td->tkbuf[0] = c;
            return td->type;
        }
    }
    CONDJMP();
    return T_NONE;
finishnum:
    strcpy(td->tkbuf, buf);
    return T_NUM;
}
